package com.lifeverse.controller;

import com.lifeverse.service.NetworkHealthMonitor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * 监控WebSocket控制器
 * 用于实时推送监控数据
 */
@Slf4j
@Controller
@RequiredArgsConstructor
public class MonitoringWebSocketController {

    private final SimpMessagingTemplate messagingTemplate;
    private final NetworkHealthMonitor networkHealthMonitor;
    private final Random random = new Random();

    /**
     * 处理心跳消息
     */
    @MessageMapping("/ping")
    @SendTo("/topic/pong")
    public Map<String, Object> handlePing(Map<String, Object> message) {
        Map<String, Object> response = new HashMap<>();
        response.put("type", "pong");
        response.put("timestamp", System.currentTimeMillis());
        response.put("serverTime", LocalDateTime.now());
        return response;
    }

    /**
     * 定时推送系统指标
     */
    @Scheduled(fixedRate = 5000) // 每5秒推送一次
    public void pushSystemMetrics() {
        try {
            Map<String, Object> metrics = new HashMap<>();
            metrics.put("type", "system_metrics");
            metrics.put("data", generateSystemMetrics());
            metrics.put("timestamp", System.currentTimeMillis());

            messagingTemplate.convertAndSend("/topic/monitoring/system", metrics);
            log.debug("推送系统指标: {}", metrics);
        } catch (Exception e) {
            log.error("推送系统指标失败", e);
        }
    }

    /**
     * 定时推送生命体指标
     */
    @Scheduled(fixedRate = 10000) // 每10秒推送一次
    public void pushLifeEntityMetrics() {
        try {
            Map<String, Object> metrics = new HashMap<>();
            metrics.put("type", "life_entity_metrics");
            metrics.put("data", generateLifeEntityMetrics());
            metrics.put("timestamp", System.currentTimeMillis());

            messagingTemplate.convertAndSend("/topic/monitoring/lifeentity", metrics);
            log.debug("推送生命体指标: {}", metrics);
        } catch (Exception e) {
            log.error("推送生命体指标失败", e);
        }
    }

    /**
     * 定时推送活动更新
     */
    @Scheduled(fixedRate = 15000) // 每15秒推送一次
    public void pushActivityUpdate() {
        try {
            Map<String, Object> activity = generateRandomActivity();
            Map<String, Object> message = new HashMap<>();
            message.put("type", "activity_update");
            message.put("data", activity);
            message.put("timestamp", System.currentTimeMillis());

            messagingTemplate.convertAndSend("/topic/monitoring/activity", message);
            log.debug("推送活动更新: {}", message);
        } catch (Exception e) {
            log.error("推送活动更新失败", e);
        }
    }

    /**
     * 定时推送告警信息
     */
    @Scheduled(fixedRate = 30000) // 每30秒检查一次
    public void pushAlerts() {
        try {
            // 随机生成告警（模拟）
            if (random.nextDouble() < 0.3) { // 30%概率生成告警
                Map<String, Object> alert = generateRandomAlert();
                Map<String, Object> message = new HashMap<>();
                message.put("type", "alert");
                message.put("data", alert);
                message.put("timestamp", System.currentTimeMillis());

                messagingTemplate.convertAndSend("/topic/monitoring/alerts", message);
                log.info("推送告警信息: {}", message);
            }
        } catch (Exception e) {
            log.error("推送告警信息失败", e);
        }
    }

    /**
     * 定时推送健康状态变化
     */
    @Scheduled(fixedRate = 20000) // 每20秒推送一次
    public void pushHealthChange() {
        try {
            if (random.nextDouble() < 0.4) { // 40%概率生成健康状态变化
                Map<String, Object> healthChange = generateHealthChange();
                Map<String, Object> message = new HashMap<>();
                message.put("type", "health_change");
                message.put("data", healthChange);
                message.put("timestamp", System.currentTimeMillis());

                messagingTemplate.convertAndSend("/topic/monitoring/health", message);
                log.debug("推送健康状态变化: {}", message);
            }
        } catch (Exception e) {
            log.error("推送健康状态变化失败", e);
        }
    }

    /**
     * 生成模拟系统指标
     */
    private Map<String, Object> generateSystemMetrics() {
        Map<String, Object> metrics = new HashMap<>();
        metrics.put("cpuUsage", 30 + random.nextInt(50)); // 30-80%
        metrics.put("memoryUsage", 40 + random.nextInt(40)); // 40-80%
        metrics.put("networkLatency", 50 + random.nextInt(150)); // 50-200ms
        metrics.put("activeConnections", 200 + random.nextInt(300)); // 200-500
        return metrics;
    }

    /**
     * 生成模拟生命体指标
     */
    private Map<String, Object> generateLifeEntityMetrics() {
        Map<String, Object> metrics = new HashMap<>();
        metrics.put("totalCount", 1200 + random.nextInt(100));
        metrics.put("activeCount", 800 + random.nextInt(200));
        metrics.put("newToday", random.nextInt(50));
        metrics.put("avgHealthScore", 60 + random.nextDouble() * 30); // 60-90
        metrics.put("networkConnections", 3000 + random.nextInt(1000));
        metrics.put("networkDensity", 0.5 + random.nextDouble() * 0.3); // 0.5-0.8
        return metrics;
    }

    /**
     * 生成随机活动
     */
    private Map<String, Object> generateRandomActivity() {
        String[] entityNames = {"智能制造公司", "深圳市", "创新概念", "混合实体001", "北京市", "AI概念"};
        String[] activityTypes = {"状态更新", "关系建立", "进化", "融合", "交互"};
        String[] entityTypes = {"corporate", "urban", "conceptual", "hybrid"};
        String[] descriptions = {
            "意识等级提升到高级", "与其他实体建立协作关系", "概念结构发生变异",
            "完成多实体融合过程", "与系统进行深度交互", "网络连接优化完成"
        };

        Map<String, Object> activity = new HashMap<>();
        activity.put("entityName", entityNames[random.nextInt(entityNames.length)]);
        activity.put("type", activityTypes[random.nextInt(activityTypes.length)]);
        activity.put("description", descriptions[random.nextInt(descriptions.length)]);
        activity.put("entityType", entityTypes[random.nextInt(entityTypes.length)]);
        activity.put("healthScore", 60 + random.nextInt(40)); // 60-100
        return activity;
    }

    /**
     * 生成随机告警
     */
    private Map<String, Object> generateRandomAlert() {
        String[] levels = {"info", "warning", "error"};
        String[] messages = {
            "系统性能优化完成", "CPU使用率持续偏高", "生命体连接异常",
            "网络延迟增加", "新生命体创建成功", "健康度监控异常"
        };
        String[] descriptions = {
            "系统性能已优化，响应速度提升20%", "系统CPU使用率在过去30分钟内持续超过80%",
            "检测到3个生命体失去网络连接", "网络延迟超过正常范围，建议检查网络状态",
            "成功创建了5个新的企业生命体", "部分生命体健康度监控出现异常"
        };

        int index = random.nextInt(messages.length);
        Map<String, Object> alert = new HashMap<>();
        alert.put("level", levels[random.nextInt(levels.length)]);
        alert.put("message", messages[index]);
        alert.put("description", descriptions[index]);
        return alert;
    }

    /**
     * 生成健康状态变化
     */
    private Map<String, Object> generateHealthChange() {
        String[] entityNames = {"智能制造公司", "深圳市", "创新概念", "混合实体001"};
        String[] changes = {"improve", "decline", "stable"};

        Map<String, Object> healthChange = new HashMap<>();
        int oldScore = 50 + random.nextInt(40); // 50-90
        int change = random.nextInt(21) - 10; // -10 to +10
        int newScore = Math.max(10, Math.min(100, oldScore + change));

        healthChange.put("entityName", entityNames[random.nextInt(entityNames.length)]);
        healthChange.put("oldScore", oldScore);
        healthChange.put("newScore", newScore);
        
        if (change > 5) {
            healthChange.put("change", "improve");
        } else if (change < -5) {
            healthChange.put("change", "decline");
        } else {
            healthChange.put("change", "stable");
        }
        
        return healthChange;
    }
}